// eee.Sheffield.PZ.Imaging
//
// Copyright ?Ping Zou, 2006
// sg71.cherub@gmail.com

using System;
using System.Collections.Generic;
using System.Text;
using eee.Sheffield.PZ.Math;
using System.Drawing;
using System.Drawing.Imaging;

namespace eee.Sheffield.PZ.Imaging.ImageFilter
{
    public class Kernel
    {
        #region static methods
        /// <summary>
        /// two dimension Gaussian kernel
        /// </summary>
        /// <param name="sigma"></param>
        /// <returns></returns>
        public static PZMath_matrix GaussianKernel2D(double sigma)
        {
            if (sigma <= 0)
                throw new ApplicationException("Kernel::GaussianKernel2D(), sigma should be positive.");
            int kernelSize = Convert.ToInt32(System.Math.Ceiling(3 * sigma));
            int kernelLength = 2 * kernelSize + 1;
            PZMath_matrix kernel = new PZMath_matrix(kernelLength, kernelLength);

            // calculate kernel element
            double sum = 0.0;
            for (int x = -1 * kernelSize; x <= kernelSize; x++)
            {
                for (int y = -1 * kernelSize; y <= kernelSize; y++)
                {
                    int ky = y + kernelSize;
                    int kx = x + kernelSize;
                    kernel[ky, kx] = System.Math.Exp(
                        -1.0 * ((double)x * (double)x + (double)y * (double)y) / sigma / sigma);
                    sum += kernel[ky, kx];
                }
            }
            for (int x = -1 * kernelSize; x <= kernelSize; x++)
            {
                for (int y = -1 * kernelSize; y <= kernelSize; y++)
                {
                    int ky = y + kernelSize;
                    int kx = x + kernelSize;
                    kernel[ky, kx] /= sum;
                }
            }

            return kernel;
        } // GaussianKernel2D
        #endregion       
    }
    
}
